home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / cpu / z8000 / 8000dasm.c next >
C/C++ Source or Header  |  1999-11-22  |  9KB  |  294 lines

  1. /*****************************************************************************
  2.  *
  3.  *     8000dasm.c
  4.  *     Portable Z8000(2) emulator
  5.  *     Z8000 disassembler; requires the z8000_exec table to be initialized
  6.  *
  7.  *     Copyright (c) 1998 Juergen Buchmueller, all rights reserved.
  8.  *     Bug fixes and MSB_FIRST compliance Ernesto Corvi.
  9.  *
  10.  *     - This source code is released as freeware for non-commercial purposes.
  11.  *     - You are free to use and redistribute this code in modified or
  12.  *       unmodified form, provided you list me in the credits.
  13.  *     - If you modify this source code, you must add a notice to each modified
  14.  *       source file that it has been changed.  If you're a nice person, you
  15.  *       will clearly mark each change too.  :)
  16.  *     - If you wish to use this for commercial purposes, please contact me at
  17.  *       pullmoll@t-online.de
  18.  *     - The author of this copywritten work reserves the right to change the
  19.  *     terms of its usage and license at any time, including retroactively
  20.  *   - This entire notice must remain in the source code.
  21.  *
  22.  *****************************************************************************/
  23.  
  24. #include <stdio.h>
  25. #include "z8000.h"
  26. #include "z8000cpu.h"
  27. #include "memory.h"
  28.  
  29. static int n[12];    /* opcode nibbles */
  30. static int b[6];    /* opcode bytes */
  31. static int w[3];    /* opcode words */
  32.  
  33. void GET_OP(int i, unsigned pc)
  34. {
  35.     UINT16 opcode = cpu_readop16(pc);
  36.     w[i] = opcode;
  37.     b[i*2+0] = opcode >> 8;
  38.     b[i*2+1] = opcode & 0xff;
  39.     n[i*4+0] = (opcode >> 12) & 0x0f;
  40.     n[i*4+1] = (opcode >> 8) & 0x0f;
  41.     n[i*4+2] = (opcode >> 4) & 0x0f;
  42.     n[i*4+3] = opcode & 0x0f;
  43. }
  44.  
  45. static char *cc[16] = {
  46.     "n",   "lt",  "le",  "ule",  "pe/ov",   "mi",  "eq/z",   "c/ult",
  47.     "a",   "ge",  "gt",  "ugt",  "po/nov",  "pl",  "ne/nz",  "nc/uge"
  48. };
  49.  
  50. static char *flg[16] = {
  51.     "",    "p/v",  "s",   "p/v,s",   "z",   "p/v,z",  "s,z",  "p/v,s,z",
  52.     "c",   "p/v,c","s,c", "p/v,s,c", "z,c", "p/v,z,c","s,z,c","p/v,s,z,c"
  53. };
  54.  
  55. static char *ints[4] = {
  56.     "",    "vi",  "nvi",   "vi,nvi"
  57. };
  58.  
  59. int DasmZ8000(char *buff, int pc)
  60. {
  61.     int new_pc = pc, i, tmp;
  62.     char *dst = buff, *src;
  63.     Z8000_exec *o;
  64.  
  65.     GET_OP(0, new_pc);
  66.     new_pc += 2;
  67.     switch (pc)
  68.     {
  69.         case 0x0000:
  70.             dst += sprintf(dst, ".word   #$%04x ;RST", w[0]);
  71.             break;
  72.         case 0x0002:
  73.             dst += sprintf(dst, ".word   #$%04x ;RST FCW", w[0]);
  74.             break;
  75.         case 0x0004:
  76.             dst += sprintf(dst, ".word   #$%04x ;RST PC", w[0]);
  77.             break;
  78.         default:
  79.             o = &z8000_exec[w[0]];
  80.             if (o->size > 1) { GET_OP(1, new_pc); new_pc += 2; }
  81.             if (o->size > 2) { GET_OP(2, new_pc); new_pc += 2; }
  82.             src = o->dasm;
  83.  
  84.             while (*src)
  85.             {
  86.                 if (*src == '%')
  87.                 {
  88.                     src++;
  89.                     switch (*src) {
  90.                     case '0': case '1': case '2': case '3':
  91.                     case '4': case '5': case '6': case '7':
  92.                         /* nibble number */
  93.                         i = *src++ - '0';
  94.                         dst += sprintf(dst, "%d", n[i]);
  95.                         break;
  96.                     case '#':
  97.                         /* immediate */
  98.                         src++;
  99.                         switch (*src++) {
  100.                             case 'b': /* imm8 (byte) */
  101.                                 i = *src++ - '0';
  102.                                 dst += sprintf(dst, "#$%02x", b[i]);
  103.                                 break;
  104.                             case 'w': /* imm16 (word) */
  105.                                 i = *src++ - '0';
  106.                                 dst += sprintf(dst, "#$%04x", w[i]);
  107.                                 break;
  108.                             case 'l': /* imm32 (long) */
  109.                                 i = *src++ - '0';
  110.                                 dst += sprintf(dst, "#$%04x%04x", w[i], w[i+1]);
  111.                                 break;
  112.                         }
  113.                         break;
  114.                     case '$':
  115.                         /* absolute immediate 8bit (rl/rr) */
  116.                         src++;
  117.                         i = *src++ - '0';
  118.                         dst += sprintf(dst, "#%d", ((INT8)b[i]<0) ? -(INT8)b[i] : b[i]);
  119.                         break;
  120.                     case '+':
  121.                         /* imm4m1 (inc/dec value) */
  122.                         src++;
  123.                         i = *src++ - '0';
  124.                         dst += sprintf(dst, "%i", n[i] + 1);
  125.                         break;
  126.                     case '*':
  127.                         /* left/right (rotate/shift) */
  128.                         src++;
  129.                         dst += sprintf(dst, "%c", b[2] ? 'r' : 'l');
  130.                         break;
  131.                     case '?':
  132.                         /* imm1or2 (shift/rotate once or twice) */
  133.                         src++;
  134.                         i = *src++ - '0';
  135.                         dst += sprintf(dst, "%c", (n[i] & 2) ? '2' : '1');
  136.                         break;
  137.                     case 'R':
  138.                         src++;
  139.                         tmp = ((n[1] & 0x01) << 16) + (n[3] << 8) + (n[7] & 0x08);
  140.                         switch (tmp)
  141.                         {
  142.                             case 0x000: dst += sprintf(dst, "inirb "); break;
  143.                             case 0x008: dst += sprintf(dst, "inib  "); break;
  144.                             case 0x010: dst += sprintf(dst, "sinirb"); break;
  145.                             case 0x018: dst += sprintf(dst, "sinib "); break;
  146.                             case 0x020: dst += sprintf(dst, "otirb "); break;
  147.                             case 0x028: dst += sprintf(dst, "outib "); break;
  148.                             case 0x030: dst += sprintf(dst, "soutib"); break;
  149.                             case 0x038: dst += sprintf(dst, "sotirb"); break;
  150.                             case 0x040: dst += sprintf(dst, "inb   "); break;
  151.                             case 0x048: dst += sprintf(dst, "inb   "); break;
  152.                             case 0x050: dst += sprintf(dst, "sinb  "); break;
  153.                             case 0x058: dst += sprintf(dst, "sinb  "); break;
  154.                             case 0x060: dst += sprintf(dst, "outb  "); break;
  155.                             case 0x068: dst += sprintf(dst, "outb  "); break;
  156.                             case 0x070: dst += sprintf(dst, "soutb "); break;
  157.                             case 0x078: dst += sprintf(dst, "soutb "); break;
  158.                             case 0x080: dst += sprintf(dst, "indrb "); break;
  159.                             case 0x088: dst += sprintf(dst, "indb  "); break;
  160.                             case 0x090: dst += sprintf(dst, "sindrb"); break;
  161.                             case 0x098: dst += sprintf(dst, "sindb "); break;
  162.                             case 0x0a0: dst += sprintf(dst, "otdrb "); break;
  163.                             case 0x0a8: dst += sprintf(dst, "outdb "); break;
  164.                             case 0x0b0: dst += sprintf(dst, "soutdb"); break;
  165.                             case 0x0b8: dst += sprintf(dst, "sotdrb"); break;
  166.                             case 0x100: dst += sprintf(dst, "inir  "); break;
  167.                             case 0x108: dst += sprintf(dst, "ini   "); break;
  168.                             case 0x110: dst += sprintf(dst, "sinir "); break;
  169.                             case 0x118: dst += sprintf(dst, "sini  "); break;
  170.                             case 0x120: dst += sprintf(dst, "otir  "); break;
  171.                             case 0x128: dst += sprintf(dst, "outi  "); break;
  172.                             case 0x130: dst += sprintf(dst, "souti "); break;
  173.                             case 0x138: dst += sprintf(dst, "sotir "); break;
  174.                             case 0x140: dst += sprintf(dst, "in    "); break;
  175.                             case 0x148: dst += sprintf(dst, "in    "); break;
  176.                             case 0x150: dst += sprintf(dst, "sin   "); break;
  177.                             case 0x158: dst += sprintf(dst, "sin   "); break;
  178.                             case 0x160: dst += sprintf(dst, "out   "); break;
  179.                             case 0x168: dst += sprintf(dst, "out   "); break;
  180.                             case 0x170: dst += sprintf(dst, "sout  "); break;
  181.                             case 0x178: dst += sprintf(dst, "sout  "); break;
  182.                             case 0x180: dst += sprintf(dst, "indr  "); break;
  183.                             case 0x188: dst += sprintf(dst, "ind   "); break;
  184.                             case 0x190: dst += sprintf(dst, "sindr "); break;
  185.                             case 0x198: dst += sprintf(dst, "sind  "); break;
  186.                             case 0x1a0: dst += sprintf(dst, "otdr  "); break;
  187.                             case 0x1a8: dst += sprintf(dst, "outd  "); break;
  188.                             case 0x1b0: dst += sprintf(dst, "soutd "); break;
  189.                             case 0x1b8: dst += sprintf(dst, "sotdr "); break;
  190.                             default:
  191.                                 dst += sprintf(dst, "??????");
  192.                         }
  193.                         break;
  194.                     case 'a':
  195.                         /* address */
  196.                         src++;
  197.                         i = *src++ - '0';
  198.                         dst += sprintf(dst, "$%04x", w[i]);
  199.                         break;
  200.                     case 'c':
  201.                         /* condition code */
  202.                         src++;
  203.                         i = *src++ - '0';
  204.                         if (n[i] == 8) {    /* always? */
  205.                             /* skip following comma */
  206.                             if (*src == ',')
  207.                                 src++;
  208.                         }
  209.                         else dst += sprintf(dst, "%s", cc[n[i]]);
  210.                         break;
  211.                     case 'd':
  212.                         /* displacement */
  213.                         src++;
  214.                         i = *src++ - '0';
  215.                         switch (i) {
  216.                             case 0: /* disp7 */
  217.                                 tmp = new_pc - 2 * (w[0] & 0x7f);
  218.                                 dst += sprintf(dst, "#$%04x", tmp);
  219.                                 break;
  220.                             case 1: /* disp8 */
  221.                                 tmp = new_pc + 2 * (INT8)(w[0] & 0xff);
  222.                                 dst += sprintf(dst, "#$%04x", tmp);
  223.                                 break;
  224.                             case 2: /* disp12 */
  225.                                 tmp = w[0] & 0x7ff;
  226.                                 if (w[0] & 0x800)
  227.                                     tmp = new_pc + 0x1000 -2 * tmp;
  228.                                 else
  229.                                     tmp = new_pc + -2 * tmp;
  230.                                 dst += sprintf(dst, "#$%04x", tmp);
  231.                                 break;
  232.                         }
  233.                         break;
  234.                     case 'f':
  235.                         /* flag (setflg/resflg/comflg) */
  236.                         src++;
  237.                         i = *src++ - '0';
  238.                         dst += sprintf(dst, "%s", flg[n[i]]);
  239.                         break;
  240.                     case 'i':
  241.                         /* interrupts */
  242.                         src++;
  243.                         i = *src++ - '0';
  244.                         dst += sprintf(dst, "%s", ints[n[i] & 3]);
  245.                         break;
  246.                     case 'p':
  247.                         /* disp16 (pc relative) */
  248.                         src++;
  249.                         i = *src++ - '0';
  250.                         dst += sprintf(dst, "$%04x", new_pc + w[i]);
  251.                         break;
  252.                     case 'r':
  253.                         /* register */
  254.                         src++;
  255.                         switch (*src++) {
  256.                             case 'b':
  257.                                 /* byte */
  258.                                 i = *src++ - '0';
  259.                                 if (n[i] & 8)
  260.                                     dst += sprintf(dst, "rl%d", n[i] & 7);
  261.                                 else
  262.                                     dst += sprintf(dst, "rh%d", n[i]);
  263.                                 break;
  264.                             case 'w':
  265.                                 /* word */
  266.                                 i = *src++ - '0';
  267.                                 dst += sprintf(dst, "r%d", n[i]);
  268.                                 break;
  269.                             case 'l':
  270.                                 /* long */
  271.                                 i = *src++ - '0';
  272.                                 dst += sprintf(dst, "rr%d", n[i]);
  273.                                 break;
  274.                             case 'q':
  275.                                 /* quad word (long long) */
  276.                                 i = *src++ - '0';
  277.                                 dst += sprintf(dst, "rq%d", n[i]);
  278.                                 break;
  279.                         }
  280.                         break;
  281.                     default:
  282.                         *dst++ = '%';
  283.                         *dst++ = *src++;
  284.                         break;
  285.                     }
  286.                 } else *dst++ = *src++;
  287.             }
  288.             *dst = '\0';
  289.             break;
  290.     }
  291.     return new_pc - pc;
  292. }
  293.  
  294.